/**
 * Tabs 相关的 TanStack Query Hooks
 * 提供标签页数据的查询、创建、更新、删除、移动、重排序功能
 */
import {useQuery, useMutation, useQueryClient} from '@tanstack/react-query';
import {QueryKeys} from '@/lib/queryClient';
import * as tabsApi from '@/api/tabs';
import {
    CreateTabRequest,
    UpdateTabRequest,
    CaptureTabsResponse,
    ListTabsByCollectionsRequest,
    TabDto,
    CollectionWithTabsDto,
} from '@/api/types';

/**
 * 获取集合下的标签页列表
 * @param collectionId - 集合 ID
 * @returns Query 对象
 */
export function useTabsByCollection(collectionId: number | null) {
    return useQuery({
        queryKey: collectionId ? QueryKeys.tabs(collectionId) : ['tabs', 'null'],
        queryFn: () => {
            if (!collectionId) {
                throw new Error('collection id is required');
            }
            return tabsApi.getTabsByCollection(collectionId);
        },
        enabled: !!collectionId,
    });
}

/**
 * 批量查询多个集合的标签页
 * @param request - 批量查询请求参数
 * @returns Query 对象
 */
export function useTabsByCollections(request: ListTabsByCollectionsRequest | null) {
    return useQuery({
        queryKey: request
            ? QueryKeys.tabsByCollections(request.space_id, request.collection_ids)
            : ['tabs', 'batch', 'null'],
        queryFn: () => {
            if (!request) {
                throw new Error('request is required');
            }
            return tabsApi.getTabsByCollections(request);
        },
        enabled: !!request && request.collection_ids.length > 0,
    });
}

/**
 * 获取单个标签页详情
 * @param tabId - 标签页 ID
 * @returns Query 对象
 */
export function useTab(tabId: number | null) {
    return useQuery({
        queryKey: tabId ? QueryKeys.tab(tabId) : ['tabs', 'null'],
        queryFn: () => {
            if (!tabId) {
                throw new Error('tab id is required');
            }
            return tabsApi.getTab(tabId);
        },
        enabled: !!tabId,
    });
}

/**
 * 创建标签页（带乐观更新）
 * @returns Mutation 对象
 */
export function useCreateTab() {
    const queryClient = useQueryClient();

    return useMutation({
        mutationFn: tabsApi.createTab,
        onMutate: async (newTab: CreateTabRequest) => {
            await queryClient.cancelQueries({
                queryKey: QueryKeys.tabs(newTab.collection_id),
            });
            const previousTabs = queryClient.getQueryData<TabDto[]>(
                QueryKeys.tabs(newTab.collection_id)
            );

            // 乐观更新：立即添加临时数据
            const optimisticTab: TabDto = {
                id: Date.now(), // 临时 ID
                collection_id: newTab.collection_id,
                url: newTab.url,
                title: newTab.title,
                favicon: newTab.favicon,
                domain: new URL(newTab.url).hostname,
                position: newTab.position ?? 0,
                is_pin: newTab.is_pin ?? false,
                owner_id: 0,
                created_at: new Date().toISOString(),
                updated_at: new Date().toISOString(),
            };

            queryClient.setQueryData<TabDto[]>(
                QueryKeys.tabs(newTab.collection_id),
                (old) => [...(old || []), optimisticTab]
            );

            return {previousTabs, collectionId: newTab.collection_id};
        },
        onSuccess: (_data, variables) => {
            queryClient.invalidateQueries({
                queryKey: QueryKeys.tabs(variables.collection_id),
            });
        },
        onError: (_err, _variables, context) => {
            if (context?.previousTabs) {
                queryClient.setQueryData(
                    QueryKeys.tabs(context.collectionId),
                    context.previousTabs
                );
            }
            console.error('create tab failed:', _err);
        },
    });
}

/**
 * 更新标签页（带乐观更新）
 * @returns Mutation 对象
 */
export function useUpdateTab() {
    const queryClient = useQueryClient();

    return useMutation({
        mutationFn: ({
            tabId,
            data,
        }: {
            tabId: number;
            collectionId?: number;
            data: UpdateTabRequest;
        }) => tabsApi.updateTab(tabId, data),
        onMutate: async (variables) => {
            // 取消所有 collections 查询，防止乐观更新被覆盖
            await queryClient.cancelQueries({
                predicate: (query) =>
                    query.queryKey[0] === 'spaces' &&
                    query.queryKey[2] === 'collections',
            });

            // 获取所有匹配的查询数据（用于回滚）
            const previousQueries = queryClient.getQueriesData({
                predicate: (query) =>
                    query.queryKey[0] === 'spaces' &&
                    query.queryKey[2] === 'collections',
            });

            // 乐观更新：立即更新缓存中的 tab 数据
            queryClient.setQueriesData<CollectionWithTabsDto[]>(
                {
                    predicate: (query) =>
                        query.queryKey[0] === 'spaces' &&
                        query.queryKey[2] === 'collections',
                },
                (old) => {
                    if (!old || !Array.isArray(old)) return old;

                    // 更新集合中的 tab
                    return old.map((collection) => ({
                        ...collection,
                        items: collection.items.map((tab) =>
                            tab.id === variables.tabId
                                ? {
                                    ...tab,
                                    title: variables.data.title ?? tab.title,
                                    url: variables.data.url ?? tab.url,
                                    domain: variables.data.url
                                        ? new URL(variables.data.url).hostname
                                        : tab.domain,
                                    position: variables.data.position ?? tab.position,
                                    is_pin: variables.data.is_pin ?? tab.is_pin,
                                    updated_at: new Date().toISOString(),
                                }
                                : tab
                        ),
                    }));
                }
            );

            return { previousQueries };
        },
        onSuccess: async (_data, _variables) => {
            // 失效并立即重新获取所有 collections 查询（确保数据一致）
            await queryClient.invalidateQueries({
                predicate: (query) =>
                    query.queryKey[0] === 'spaces' &&
                    query.queryKey[2] === 'collections',
                refetchType: 'active', // 立即重新获取活跃的查询
            });
        },
        onError: (_err, _variables, context) => {
            // 失败时回滚所有查询数据
            if (context?.previousQueries) {
                context.previousQueries.forEach(([queryKey, data]) => {
                    queryClient.setQueryData(queryKey, data);
                });
            }
            console.error('update tab failed:', _err);
        },
    });
}

/**
 * 删除标签页
 * @returns Mutation 对象
 */
export function useDeleteTab() {
    const queryClient = useQueryClient();

    return useMutation({
        mutationFn: ({
            tabId,
        }: {
            tabId: number;
            collectionId?: number;
        }) => tabsApi.deleteTab(tabId),
        onSuccess: async (_data, _variables) => {
            // 失效并立即重新获取所有 collections 查询（因为我们使用聚合接口）
            await queryClient.invalidateQueries({
                predicate: (query) =>
                    query.queryKey[0] === 'spaces' &&
                    query.queryKey[2] === 'collections',
                refetchType: 'active', // 立即重新获取活跃的查询
            });
        },
        onError: (_err) => {
            console.error('delete tab failed:', _err);
        },
    });
}

/**
 * 批量采集浏览器窗口标签
 * 创建一个新的集合并将浏览器窗口内的所有标签批量写入该集合
 * @returns Mutation 对象
 */
export function useCaptureTabs() {
    const queryClient = useQueryClient();

    return useMutation({
        mutationFn: tabsApi.captureTabs,
        onSuccess: (data: CaptureTabsResponse) => {
            // 使该空间下的集合缓存失效
            queryClient.invalidateQueries({
                queryKey: QueryKeys.collections(data.collection.space_id),
            });
            // 使新集合的标签页缓存失效
            queryClient.invalidateQueries({
                queryKey: QueryKeys.tabs(data.collection.id),
            });
        },
        onError: (_err) => {
            console.error('capture tabs failed:', _err);
        },
    });
}

/**
 * 批量重排或移动标签页
 * 组件层已做同步乐观更新和失败回滚，Hook 只负责：
 * - onSuccess: 合并后端返回的最新数据（updated_at 等）
 * @returns Mutation 对象
 */
export function useReorderTabs() {
    const queryClient = useQueryClient();

    return useMutation({
        mutationFn: tabsApi.reorderTabs,
        onSuccess: (updatedTabs) => {
            // 合并后端返回的最新数据（含 updated_at 等服务端字段）
            if (updatedTabs && updatedTabs.length > 0) {
                queryClient.setQueriesData<CollectionWithTabsDto[]>(
                    {
                        predicate: (query) =>
                            query.queryKey[0] === 'spaces' &&
                            query.queryKey[2] === 'collections',
                    },
                    (old) => {
                        if (!old || !Array.isArray(old)) return old;

                        const updatedMap = new Map(updatedTabs.map(tab => [tab.id, tab]));

                        return old.map(collection => {
                            const hasUpdates = collection.items.some(tab => updatedMap.has(tab.id));
                            if (!hasUpdates) return collection;

                            return {
                                ...collection,
                                items: collection.items.map(tab => {
                                    const updated = updatedMap.get(tab.id);
                                    return updated || tab;
                                }).sort((a, b) => a.position - b.position),
                            };
                        });
                    }
                );
            }
        },
    });
}
